/**----------------------------------------
 * @description 层管理器，启动场景时自动运行，生命周期和场景同步
 * @author      lxc
 * @file        LayerMgr.ts
 * @Date        2022-05-05
 * @version     1.0.0
 * ----------------------------------------
 */
import { LayerSign } from "../../Constant";
import { MsgComponent } from "../message/MsgComponent";
import { LayerPrefab, PrefabPath } from "../resource/PathConstant";
import { DialogLayer } from "./DialogLayer";
import { ToastLayer } from "./ToastLayer";

const {ccclass, property} = cc._decorator;

@ccclass
export class LayerMgr extends MsgComponent {

    @property(cc.Node)
    background : cc.Node = null;

    @property(cc.Node)
    touchLayer : cc.Node = null;

    @property(cc.Node)
    uiLayer : cc.Node = null

    @property(cc.Node)
    functionalLayer : cc.Node = null;

    @property(cc.Node)
    effectLayer : cc.Node = null;

    @property(cc.Node)
    dialogLayer : cc.Node = null;

    @property(cc.Node)
    toastLayer : cc.Node = null;

    @property(cc.Node)
    frontAnimLayer : cc.Node = null;

    @property(cc.Node)
    testLayer : cc.Node = null;

    private layers: Map<LayerSign, cc.Node> = new Map();

    protected onLoad(): void {
        this.layers.set(LayerSign.Background, this.background);
        this.layers.set(LayerSign.TouchLayer, this.touchLayer);
        this.layers.set(LayerSign.UILayer, this.uiLayer);
        this.layers.set(LayerSign.FunctionalLayer, this.functionalLayer);
        this.layers.set(LayerSign.EffectLayer, this.effectLayer);
        this.layers.set(LayerSign.DialogLayer, this.dialogLayer);
        this.layers.set(LayerSign.ToastLayer, this.toastLayer);
        this.layers.set(LayerSign.FrontAnimLayer, this.frontAnimLayer);
        this.layers.set(LayerSign.TestLayer, this.testLayer);

        gVar.TestLayer = this.testLayer;  // 不用查找节点的方法是因为测试这样更高效(烂代码属于是)
        this.bindLayerMgrComponent()
    }
    /**
     * 绑定层对应的管理组件
     */
    bindLayerMgrComponent(){
        this.toastLayer.addComponent(ToastLayer);
        this.dialogLayer.addComponent(DialogLayer);
        this.addToLayer(LayerPrefab.testLayer,LayerSign.TestLayer,LayerPrefab.testLayer)
        gVar.UIMsgMgr.dispatchMsg(LocalMsg.ModuleInitDone);
    }

    initListeners(): void {
        super.initListeners()
        this.addUIListener(LocalMsg.AddToLayer,this.addToLayer.bind(this))
        this.addUIListener(LocalMsg.AddNodeToLayer,this.addNodeToLayer.bind(this))
        this.addUIListener(LocalMsg.FindNodeByLayer,this.findNodeByLayer.bind(this))
        // 查找某个节点或者对象在某个层是否存在
    }
    /**
     * 将预制体添加到指定节点上
     * @param path 
     * @param layersign 
     * @param identifier 节点标识符
     */
    addToLayer(path : PrefabPath,layersign : LayerSign, identifier?:string){
        gVar.ResMgr.loadPrefab(path, (prefab : cc.Prefab) => {
            let node = cc.instantiate(prefab)
            identifier && (node.name = identifier)
            node.parent = this.layers.get(layersign);
        })
    }
    /**
     * 将节点添加到层上
     * @param node 
     * @param layersign 
     * @param identifier 节点标识符
     */
    addNodeToLayer(node : cc.Node,layersign: LayerSign, identifier?:string){
        identifier && (node.name = identifier)
        node.parent = this.layers.get(layersign);
    }
    /**
     * 根据名称查找对应节点
     * @param identifier 
     * @param completeFunc 
     * @param layerSign 
     */
    findNodeByLayer(identifier:string,completeFunc:Function,layerSign ?: LayerSign){
        let node = null
        if(layerSign){
            node = this.layers.get(layerSign).getChildByName(identifier);
            completeFunc(node)
        }else{
            this.layers.forEach((layer)=>{
                node = layer.getChildByName(identifier)
                if(node){
                    completeFunc(node)
                }
            })
        }
    }
}